package serviceImpl;

import Dao.CarDao;
import Dao.RecordDao;
import Dao.UserDao;
import pojo.Car;
import pojo.Record;
import pojo.User;
import service.UserService;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 用户功能类
 * 注意：用户看不到未上架的车
 */
public class UserServiceImpl implements UserService {

    /**
     * 登录
     * @param name 用于比较的用户名
     * @param password 用于比较的密码
     * @return 标记登录成功或失败
     */
    @Override
    public User sign_in(String name, String password) {
        //遍历集合
        for (User user : UserDao.getUsers()) {
            //判断传入的用户名和密码是否和集合中对象中的用户名和密码相同
            if (user.getName().equals(name)&&user.getPassword().equals(password)){
                //返回用户
                return user;
            }
        }
        return null;
    }

    /**
     * 注册
     * @param name 注册用的用户名
     * @param password 注册用的密码
     * @return
     */
    @Override
    public void login(String name, String password) {
        //用传入的用户名和密码 创建新用户
        User user = new User(name, password, false);
        //将新用户添加入用户集合
        UserDao.getUsers().add(user);
    }

    /**
     * 根据汽车id 租车   将所租车辆加入RecordDao.getRecords集合 并且将此车的rent改额为false
     * @param id
     * @param user
     * @return
     */
    @Override
    public Record rent(int id, User user)  {
        Car car=null;
        //遍历汽车集合
        for (Car car1 : CarDao.getCars()) {
            //将传入id和集合内车的id作比较
            if (id==car1.getId()){
                //获得需要租的车
                car = car1;
            }
        }
        //将车辆的可租状态变为不可租
        car.setRent(false);

        CarDao.setCars();
        //创建所租车对象
        Car reCordCar=new Car(car.getId(),car.getName(),car.getRemark(),car.getBrand(),car.getType(),car.getPrice(),false,car.isStatus(),car.getCardNumber(),car.getCarPrice(),car.getColor());
        //获得订单编号
        int recordId=RecordDao.getRecords().size()==0?1:RecordDao.getRecords().get(RecordDao.getRecords().size()-1).getId()+1;
        //创建订单对象
        Record record = new Record(recordId, user, reCordCar);
        //设置租车时间
        record.setRentTime(new Date());
        RecordDao.setRecords();
        //将订单加入订单集合
        RecordDao.getRecords().add(record);
        RecordDao.setRecords();
        return record;

    }
    /**
     *排序
     * @param choice 1:降序   2：升序
     * @return
     */
    @Override
    public ArrayList<Car> sort(String choice) {
        //判断升降序
        if (choice.equals("1")) {
            return (ArrayList<Car>) CarDao.getCars().stream().sorted(Comparator.comparing(Car::getPrice).reversed()).collect(Collectors.toList());
        }else  if (choice.equals("2")){
            return (ArrayList<Car>) CarDao.getCars().stream().sorted(Comparator.comparing(Car::getPrice)).collect(Collectors.toList());
        }
        return null;

    }
    /**
     * 根据类型搜索车辆
     * @param type 传入类型
     * @return
     */
    @Override
    public ArrayList<Car> type(String type) {
        //用Stream流过滤
        Stream<Car> carStream = CarDao.getCars().stream().filter(car -> car.getType().equals(type));
        //用于判断类型是否存在
        long a = carStream.count();
        if (a!=0){
            ArrayList<Car> cars = (ArrayList<Car>) carStream.collect(Collectors.toList());
            return cars;
        }else {
            return null;
        }
    }
    /**
     * 根据品牌搜索车辆
     * @param brand 传入品牌
     *
     * @return
     */
    @Override
    public ArrayList<Car> brand(String brand) {
        //创建新集合  用于储存传入品牌的车辆
        ArrayList<Car> cars=new ArrayList<>();
        //用于判断品牌是否存在
        boolean a=false;
        //遍历集合
        for (Car car : CarDao.getCars()) {
            //如果品牌编号相同
            if ((car.getBrand().charAt(car.getBrand().indexOf("(") +1)+"").equals(brand)){
                //将车加入集合
                cars.add(car);
                a=true;
            }
        }
        if (a){
            return cars;
        }else {
            return null;
        }
    }

    /**
     * 打印所有汽车
     * @param user 调用功能的用户
     */
    @Override
    public void showAllCar(User user) {
        System.out.println("编号\t汽车名称\t备注\t\t品牌\t\t类型\t\t\t价格\t\t是否可租");
        for (Car car : CarDao.getCars()) {
            //用户判断是否是管理员
            if (user.isAdmin()){
                System.out.println(car+"  "+(car.isRent()?"是":"否"));

            }else{
                //判断汽车是否上架
                if (car.isStatus()){
                    System.out.println(car+"  "+(car.isRent()?"是":"否"));
                }
            }
        }
    }

    /**
     * 查看租车记录 注意：只能看自己的的租车记录
     * @return
     */
    @Override
    public ArrayList<Record> carRent() {
        //返回订单
        return RecordDao.getRecords();
    }

    /**
     * 根据id还车
     * @param id 需要还的车的id
     * @param user 借车的用户
     * @return 返回租车订单
     */
    @Override
    public Record backCar(int id, User user) {
        Record r = null;
        //遍历订单集合
        for (Record record : RecordDao.getRecords()) {
            //判断传入id是否在集合中 借车人是否是本人
            if (record.getCar().getId()==id&&record.getUser().getName().equals(user.getName())&&record.getBackTime()==null){
                //设置订单的还车时间
                record.setBackTime(new Date());
                RecordDao.setRecords();
                r=record;
                //循环遍历集合
                for (Car car : CarDao.getCars()) {
                    //将所还车辆的可租状态设置为可租
                    if (car.getId()==id){
                        car.setRent(true);
                        CarDao.setCars();
                    }
                }

            }

        }
        return r;
    }

    /**
     * 传入两个时间计算差值
     * @param rent 借车时间
     * @param back 还车时间
     * @return 返回相差天数 不足一天算一天
     */
    @Override
    public int getDay(Date rent, Date back) {
        //得到租车时间的日历类对象
        Calendar rentCld=Calendar.getInstance();
        rentCld.setTime(rent);
        //得到还车时间的日历类对象
        Calendar backCld=Calendar.getInstance();
        backCld.setTime(back);
        //计算相差天数
        int day =((int)(backCld.getTimeInMillis()-rentCld.getTimeInMillis())/1000/60/60/24)+1;
        return day;
    }

}
